/**
 * Copyright (c) 快宝网络 kuaidihelp.com Co., Ltd. All Rights Reserved 禁止外泄以及用于其它的商业用途
 */

import cryptoCfg from './request-config';
import qs from 'qs';
import { useCallback, useEffect, useMemo, useState } from 'react';
import { debounce, isPlainObject, isArray } from 'lodash';
import requestCrypto from './request-crypto';
import MD5 from 'crypto-js/md5';

/**
 *
 * @description 提取数据，支持层级json
 * @param {*} key
 * @param {*} data
 * @returns
 */
function pickData(key, data) {
  const keys = isArray(key) ? key : key.split('.');
  const [k, ...restKeys] = keys;
  let restData = data[k];
  if (restKeys.length === 0) {
    return isPlainObject(restData) ? JSON.stringify(restData) : restData;
  }
  try {
    restData = JSON.parse(restData);
  } catch (error) {
    console.log('error', error);
  }
  return pickData(restKeys, restData);
}

/**
 *
 * @description 创建nonce
 * @param {string} key
 * @param {any} data
 * @returns {string}
 */
function createNonceData(key, data) {
  if (key && data) {
    const [useMd5, other = useMd5] = key.split(':');
    const arr = other.split(',');
    const nonce = arr
      .map(item => pickData(item, data))
      .filter(item => !!item)
      .join('');
    return useMd5 !== 'md5' ? nonce : `${MD5(nonce)}`;
  }
  return '';
}

/**
 *
 * @description 加密请求地址
 * @param  {CryptoParams} params
 * @returns
 */
export function crypto(params) {
  return new Promise(resolve => {
    let { url } = params;
    url = url.trim();
    const { appId: app_id } = cryptoCfg || {};
    if (!app_id) {
      resolve(url);
      return;
    }
    const { options } = params;
    const { nonceKey, body, data = body, params: optsParams } = options || {};

    const nonceData = createNonceData(nonceKey, {
      ...(typeof data === 'string' ? qs.parse(data) : data),
      ...optsParams,
    });
    const ready = requestCrypto();
    ready.then(ins => {
      const sessionId = window.sessionId || '';
      const [url_] = url.split('?');
      const [sign, nonce, ts] = ins.KbCryptoHelper.buildDigest(url_, app_id, sessionId, nonceData);
      resolve(
        `${url}${url.includes('?') ? '&' : '?'}${qs.stringify({
          sign_n: sign,
          nonce_n: nonce,
          ts_n: ts,
          app_id_n: app_id,
        })}`,
      );
    });
  });
}

/**
 *
 * @description 加密请求
 * @param url
 * @returns
 */

export function useCrypto(opts, deps = []) {
  const { uri: optsUri, data = null, nonceKey } = opts;
  const [uriWithSign, setUriWithSign] = useState('');
  const [loading, setLoading] = useState(false);

  const update = useCallback(
    debounce(
      (u = optsUri) => {
        setLoading(true);
        return crypto({
          url: u,
          options: {
            nonceKey,
            data,
          },
        })
          .then(setUriWithSign)
          .finally(() => setLoading(false));
      },
      300,
      { trailing: true, leading: false },
    ),
    [optsUri],
  );

  useEffect(
    () => {
      update(optsUri);
    },
    [optsUri, ...deps],
  );

  const uri = useMemo(
    () => {
      if (!data) return uriWithSign;
      return `${uriWithSign}&${qs.stringify(data)}`;
    },
    [uriWithSign],
  );

  return { uri, loading, update };
}
